package service;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import model.VadeMecumMultimedia;
import persistence.VadeMecumMultimediaDAO;
import util.Base64Util;
import util.VadeMecumConstants;

public class VadeMecumMultimediaService {
	
	private VadeMecumMultimediaDAO dao;
	
	private final String separator = System.getProperty("file.separator");
	
	private final String filesDirectory = VadeMecumConstants.UPLOAD_DIRECTORY;

	private String endl = System.getProperty("line.separator");
	
	public VadeMecumMultimediaService() {
		dao = VadeMecumMultimediaDAO.getInstance();
	}
	
	public void saveWithoutContext(String fileName, String fileEncondedBase64) {
		String fileURL = filesDirectory + separator + fileName; 
		File toSave = new File(fileURL);
		try {
			FileOutputStream foe = new FileOutputStream(toSave);
			foe.write(Base64Util.decode(fileEncondedBase64));
			foe.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String filetype = getFileType(fileName);
		dao.saveOrUpdate(new VadeMecumMultimedia(fileURL, filetype));
	}
	
	public void saveWithContext(String fileName, String fileByteArrayEncodedBase64, String contextByteArrayEncodedBase64) {
		String fileURL = filesDirectory + separator + fileName; 
		File toSave = new File(fileURL);
		try {
			FileOutputStream foe = new FileOutputStream(toSave);
			foe.write(Base64Util.decode(fileByteArrayEncodedBase64));
			foe.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String context = Base64Util.decodeToString(contextByteArrayEncodedBase64);
		String filetype = getFileType(fileName);
		dao.saveOrUpdate(new VadeMecumMultimedia(fileURL, filetype, context));
	}
	
	public String queryAll() {
		List<VadeMecumMultimedia> files = dao.getAllFiles();
		if (!files.isEmpty()) { 
			StringBuilder sb = new StringBuilder();
			for (VadeMecumMultimedia f : files) {				
				sb.append(f.getId());
				sb.append(" ");
				String url = f.getfileurl();
				
				String name = url.substring(url.lastIndexOf(separator)+1, url.length());
				sb.append(name + "#");
//				sb.append(endl);
			}
			return sb.toString();
		}
		return null;
	}
	
	public String getFile(Integer id) {
		try {
			VadeMecumMultimedia file = dao.getFilebyId(id);
			if (file != null) {
				String filePath = file.getfileurl().trim();

				File f = new File(filePath);
				FileInputStream fis = new FileInputStream(f);
				DataInputStream dis = new DataInputStream(fis);

				List<Byte> byteList = new ArrayList<Byte>();
				byte[] byteArray = null;

				try {				
					while (true) {
						byteList.add(dis.readByte());
					}
				} catch (EOFException eofe) {
					//eof
					byteArray = toByteArray(byteList);
				}

				if (byteArray == null) {
					throw new RuntimeException("File not found on disk");
				} else {
					return Base64Util.encodeBytes(byteArray);
				}
			} else {
				throw new RuntimeException("File not exists");
			}
		} catch (IOException ioe) {			
			ioe.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new RuntimeException("Unknown error");
	}
	
	private byte[] toByteArray(List<Byte> byteList) {
		byte[] toReturn = new byte[byteList.size()];
		int i = 0;
		for (Byte b : byteList) {
			toReturn[i] = b.byteValue();
			i++;
		}
		return toReturn;
	}

	private String getFileType(String fileName) {
		String type = null;
		
		if (fileName.endsWith(".jpg")) {
			type = VadeMecumConstants.IMAGE_TYPE;
		} else if (fileName.endsWith(".mpg")) {
			type = VadeMecumConstants.VIDEO_TYPE;
		} else if (fileName.endsWith(".wav")) {
			type = VadeMecumConstants.AUDIO_TYPE;
		} else if (fileName.endsWith(".txt")) {
			type = VadeMecumConstants.TEXT_TYPE;
		}
		
		return type == null ? "unknown" : type;
	}
	
}

